/*
 * server.hpp
 *
 *  Created on: Nov 18, 2010
 *      Author: daniel
 */

#ifndef DP_WA_SERVER_HPP_
#define DP_WA_SERVER_HPP_

#include <set>
#include <doeplus/webapp/defines.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <doeplus/webapp/connection.hpp>
#include <doeplus/webapp/http_exception.hpp>

namespace doeplus{ namespace webapp{


/**
 * The server class is the main webapp class.
 * A server defines on what port the server is running.
 * Do not confuse the server with the actual application itself.
 * A server can contain several instances of the application, where
 * each application has it's own settings.
 */
class server  {

public:
	typedef boost::function1<bool,doeplus::webapp::connection::ptr> connection_handler;
	typedef boost::function2<void,doeplus::webapp::connection::ptr,int> error_handler;

	enum status_codes{
		HTTP_OK = 200,
		HTTP_not_found	= 404,
		HTTP_error_parsing_request	= 400,
		HTTP_internal_server_error = 500
	};

protected:
	boost::asio::io_service& _io_service;
	connection_handler _connection_callback;
	error_handler _error_callback;

	typedef std::set<connection::ptr> connection_set;
	connection_set _active_connections;
	connection_set _closed_connections;

public:
	string_map default_headers;

	connection_handler& connection_callback(){
		return _connection_callback;
	}
	error_handler& error_callback(){
		return _error_callback;
	}

	boost::asio::io_service& get_io_service(){
		return this->_io_service;
	}

	void handle_error(doeplus::webapp::connection::ptr connection,doeplus::webapp::http_exception &e){
//		if(this->_error_callback){
//			this->_error_callback(connection,error);
//		}else{
			connection->response_code	= e.error_code();
			static std::string errorMsg(e.what());
			connection->send_response(errorMsg,true);
//		}
	}

	/**
	 * Constructor
	 */
	server(boost::asio::io_service& io_service) : _io_service(io_service){
		this->default_headers["Content-Type"]	= "text/html; charset=UTF-8";
		this->default_headers["Server"]			= "doeplus webapp 0.1";
	}

	void _remove_connection(connection::ptr connection){
		this->_active_connections.erase(connection);
	}

};



} }	// doeplus::fcgi

#endif /* SERVER_HPP_ */

